home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / mus / play / tracker_3_19.lzh / tracker / open.c < prev    next >
C/C++ Source or Header  |  1993-11-17  |  5KB  |  244 lines

  1. /* open.c */
  2.  
  3. /* Magic open file: path lookup and transparent decompression */
  4.  
  5. /* $Id: open.c,v 3.9 1993/11/17 15:31:16 espie Exp espie $ 
  6.  * $Log: open.c,v $
  7.  * Revision 3.9  1993/11/17  15:31:16  espie
  8.  * *** empty log message ***
  9.  *
  10.  * Revision 3.8  1993/11/11  20:00:03  espie
  11.  * Amiga support.
  12.  *
  13.  * Revision 3.7  1993/08/17  16:53:09  espie
  14.  * New gzip suffix.
  15.  *
  16.  * Revision 3.3  1993/07/14  16:33:41  espie
  17.  * Added gzip/shorten.
  18.  *
  19.  * Revision 3.2  1992/12/03  15:00:50  espie
  20.  * restore stty.
  21.  *
  22.  * Revision 3.1  1992/11/19  20:44:47  espie
  23.  * Protracker commands.
  24.  *
  25.  * Revision 3.0  1992/11/18  16:08:05  espie
  26.  * New release.
  27.  *
  28.  * Revision 1.5  1992/11/01  13:10:06  espie
  29.  * Cleaned up path handler, and some more bugs.
  30.  * Check for size now.
  31.  * Added path support. Transparent interface. We look up through the file
  32.  * list, which is small anyway.
  33.  */
  34.  
  35. #include <stdio.h>
  36. #include <string.h>
  37. #include <ctype.h>
  38. #ifdef AMIGA
  39. #include <stdlib.h>
  40. #else
  41. #include <malloc.h>
  42. #endif
  43.  
  44. #include "defs.h"
  45. #include "extern.h"
  46.  
  47. LOCAL char *id = "$Id: open.c,v 3.9 1993/11/17 15:31:16 espie Exp espie $";
  48.  
  49. #define MAX_DESC 50 /* Maximum number of opened files */
  50.  
  51. LOCAL struct exfile 
  52.     {
  53.     FILE *handle;
  54.     int type;
  55.     } desc[MAX_DESC];
  56.  
  57. LOCAL int ixfile = 0;
  58.  
  59. #define REALFILE 1
  60. #define PIPEFILE 2
  61.  
  62. /* compression methods we do know about.
  63.  * Important restriction: for the time being, the output
  64.  * must be a single module.
  65.  */
  66.  
  67. LOCAL struct compression_method
  68.     {
  69.     char *extension;
  70.     char *command;
  71.     } comp_table[] =
  72.     {
  73.     ".gz",    "gzip -dc %s",
  74. #ifdef GZIP
  75.     ".z",    "gzip -dc %s",
  76. #else
  77.     ".Z",   "zcat %s",
  78. #endif
  79.     ".s",    "shorten -x %s -",
  80.     ".shn",    "shorten -x %s -",
  81.     ".zoo", "zoo xpq %s",
  82. #ifdef AMIGA
  83.     ".lzh", "lha -q p %s",
  84.     ".lha", "lha -q p %s",
  85. #else
  86.     ".lzh", "lha pq %s",
  87.     ".lha", "lha pq %s",
  88. #endif
  89.     ".zip", "unzip -pqq %s",
  90.     ".arc", "arc pn %s",
  91.     NULL,   NULL
  92.     };
  93.  
  94. /***
  95.  *
  96.  *  Handling extensions.
  97.  *
  98.  ***/
  99.  
  100. LOCAL BOOL check_ext(s, ext)
  101. char *s, *ext;
  102.     {
  103.     int ext_len, s_len;
  104.     char *c;
  105.  
  106.     ext_len = strlen(ext);
  107.     s_len = strlen(s);
  108.     if (s_len < ext_len)
  109.         return FALSE;
  110.     for (c = s + s_len - ext_len; *c; c++, ext++)
  111.         if (tolower(*c) != tolower(*ext))
  112.             return FALSE;
  113.     return TRUE;
  114.     }
  115.  
  116. LOCAL BOOL exist_file(fname)
  117. char *fname;
  118.     {
  119.     FILE *temp;
  120.  
  121.     temp = fopen(fname, "r");
  122.     if (temp)
  123.         {
  124.         fclose(temp);
  125.         return TRUE;
  126.         }
  127.     else
  128.         return FALSE;
  129.     }
  130.  
  131. #ifndef MAXPATHLEN
  132. #define MAXPATHLEN 350
  133. #endif
  134.  
  135. LOCAL char *find_file(fname, path)
  136. char *fname;
  137. char *path;
  138.     {
  139.     char *sep;
  140.     static char buffer[MAXPATHLEN];
  141.     int len;
  142.  
  143.         /* first, check the current directory */
  144.     if (exist_file(fname))
  145.         return fname;
  146.     while(path)
  147.         {
  148.         sep = strchr(path, ':');
  149.         if (sep)
  150.             len = sep - path;
  151.         else
  152.             len = strlen(path);
  153.         if (len < MAXPATHLEN)
  154.             {
  155.             strncpy(buffer, path, len);
  156.             buffer[len] = '/';
  157.             if (len + strlen(fname) < MAXPATHLEN - 5)
  158.                 {
  159.                 strcpy(buffer + len + 1, fname);
  160.                 puts(buffer);
  161.                 if (exist_file(buffer))
  162.                     return buffer;
  163.                 }
  164.             }
  165.         if (sep)
  166.             path = sep + 1;
  167.         else
  168.             return NULL;
  169.         }
  170.     return NULL;
  171.     }
  172.  
  173. FILE *open_file(fname, mode, path)
  174. char *fname;
  175. char *mode; /* right now, only mode "r" is supported */
  176. char *path; 
  177.     {
  178.     struct exfile *new;
  179.     struct compression_method *comp;
  180.  
  181.     if (mode[0] != 'r' || mode[1] != 0)
  182.         return NULL;
  183.     
  184.     if (ixfile == MAX_DESC)
  185.         return NULL;
  186.  
  187.     new = desc + ixfile++;
  188.  
  189.     fname = find_file(fname, path);
  190.     if (!fname)
  191.         return NULL;
  192.     for (comp = comp_table; comp->extension; comp++)
  193.         if (check_ext(fname, comp->extension))
  194.             {
  195.             char pipe[MAXPATHLEN + 25];
  196.  
  197.             sprintf(pipe, comp->command, fname);
  198.             new->type = PIPEFILE;
  199.             if (new->handle = popen(pipe, "r"))
  200.                 return new->handle;
  201.             else
  202.                 {
  203.                 ixfile--;
  204.                 return NULL;
  205.                 }
  206.             }
  207.     new->type = REALFILE;
  208.     if (new->handle = fopen(fname, "r"))
  209.         return new->handle;
  210.     else
  211.         {
  212.         ixfile--;
  213.         return NULL;
  214.         }
  215.     }
  216.  
  217.  
  218. void close_file(file)
  219. FILE *file;
  220.     {
  221.     if (file)
  222.         {
  223.         int i;
  224.  
  225.         for (i = 0; i < ixfile; i++)
  226.             if (desc[i].handle == file)
  227.                 {
  228.                 switch(desc[i].type)
  229.                     {
  230.                 case REALFILE:
  231.                     fclose(file);
  232.                     break;
  233.                 case PIPEFILE:
  234.                     pclose(file);
  235.                     break;
  236.                     }
  237.                 ixfile--;
  238.                 desc[i].handle = desc[ixfile].handle;
  239.                 desc[i].type = desc[ixfile].type;
  240.                 }
  241.             }
  242.     }
  243.  
  244.